/*
 * $Library: Moyrax Core $
 * $Module: Object-Oriented Programming Emulation $
 * $Date: 2008/01/28 23:35:17 $
 * $Rev: @REV $
 */

Function.prototype.extend({
	/**
	 * Hereda una clase y devuelve la nueva clase heredada.
	 *
	 * @param Super  Clase de la cual se heredará la interfaz.
	 */
	inherit : function(Super) {
		if ( !Super )
			return(false);

		var Self = this;
		var fNew = window.createInterface(this.name, function() {
			Self.apply(this, arguments);
		}, new Self(), new Super());

		return(function() {
			var p = fNew.apply(this, arguments);

			return(p);
		});
	},
	/**
	 * Devuelve una sola instancia de la clase, para
	 * utilizar como un singleton.
	 */
	getInstance : function(args){
		if ( !$.isDef(this.getInstance.instance) ) {
			this.getInstance.instance = new this(args);
		}

		return( this.getInstance.instance );
	}
});
Object.prototype.extend({
	/**
	 * Recorre una Coleción, pasándole cada elemento a una
	 * función definida por el usuario. Si la función devolviera
	 * BREAK, se interrumpirá la ejecución del bucle.
	 *
	 * @param proc   Puntero a la función que recibirá cada elemento.
	 * @param start  Límite inferior desde el cual se deberá comenzar a contar.
	 * @param end    Límite superior hasta el cuál se deberá recorrer.
	 * @param step   Cuántos saltos se darán entre cada iteración.
	 * @param owner  Objeto en cuyo contexto será ejecutado el bucle.
	 * @return       Devuelve el valor retornado por la función proc.
	 */
	each : function(proc, start, end, step, owner) {
		if ( !this.length )
			return(false);

		var pArr = this.toArray(start, end, step);

		owner = owner || this;

		return(pArr.each(function(p, i)
		{
			return(proc.apply(owner, [p, i]));
		}, start, end, step, owner));
	},
	/**
	 * Convierte un Objeto o Colección en Array.
	 *
	 * @param start  Límite inferior desde el cual se deberá comenzar a contar.
	 * @param end    Límite superior hasta el cuál se deberá recorrer.
	 * @param step   Cuántos saltos se darán entre cada iteración.
	 */
	toArray : function(start, end, step) {
		var arrObj = [];

		start = start || 0;
 		end = end || 0;
		step = step || 1;

		if ( $.isDef(this.length) ) {
			end = end || this.length;

			for (var i = start; i < end; i += step) {
				arrObj.push( this[i] );
			}
		}
		else {
			var reserved = "extend";
			var item = 0;

			for (var p in this) {
				if ( (item >= start) && (end ? (item <= end) : 1) &&
					 (item % step == 0) )
				{
					if ( !$syscalls().exists(p) && (p != reserved) ) {
						arrObj.push(p);
					}
				}

				item++;
			}
		}

		return(arrObj);
	}
});
